package cn.stylefeng.guns.rabbitmq.service.impl;

import cn.stylefeng.guns.rabbitmq.common.ProductData;
import cn.stylefeng.guns.rabbitmq.config.RenStatusMsg;
import cn.stylefeng.guns.rabbitmq.config.ShouKaStatusMsg;
import cn.stylefeng.guns.rabbitmq.model.ResultParam;
import cn.stylefeng.guns.rabbitmq.service.ICardService;
import cn.stylefeng.guns.rabbitmq.util.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service("shouKaCardService")
@Slf4j
public class ShoukaCardServiceImpl implements ICardService {
    private static final String customerId = "18771118457";
    private static final String signKey = "a224d23317b22c1748e9659a3b449034";
    private static final String paramKey = "shoukala.1234~~!";

    @Value("${order.approveUrl}")
    private String approveUrl;

    /**
     * 发送
     *
     * @param object
     */
    @Override
    public boolean sendCardSubmit(JSONObject object) {
        log.info("收卡啦销卡接收到数据：" + object.toJSONString() + "，开始提交数据到收卡啦销卡");
        JSONObject order = object.getJSONObject("order");
        JSONObject orderItem = object.getJSONObject("orderItem");
        JSONObject channel = object.getJSONObject("channel");
        JSONArray channelParam = channel.getJSONArray("params");
        String httpUrl = channel.getString("apiUrl");
        Map<String, String> param = new HashMap<>();
        //先拆分固定参数
        for (Object objParam : channelParam) {
            JSONObject jsonObject = (JSONObject)objParam;
            if (!StringUtils.isEmpty(jsonObject.getString("value"))) {
                param.put(jsonObject.getString("key"), jsonObject.getString("value"));
            }
        }
        try {
            Integer quota = order.getIntValue("quota");
            String operatorCode = param.get("operatorCode");
            String operatorName = param.get("name");
            param.put("userCode", customerId);
            param.put("dateTime", DateUtil.DateToString(new Date(), DateStyle.YYYYMMDDHHMMSS));
            String retUrl = param.get("retUrl");
            param.put("userOrderNo", order.getString("orderNo"));
            param.put("cardNo", orderItem.getString("cardNo"));
            param.put("cardPwd", ShouKaUtil.encrypt(orderItem.getString("cardPassword"),  paramKey));
            //如果产品Id为空，那么请求获取，放入内存中
            String nameMd5 = EncryptionUtil.getMD5(operatorName);
            if (ProductData.productMap.get(operatorCode + nameMd5) == null) {
                Map<String, String> proCodeMap  = getProductId(operatorCode, operatorName);
                if (proCodeMap != null) {
                    ProductData.productMap.put(operatorCode + nameMd5, proCodeMap);
                    String productId = proCodeMap.get(quota.toString());
                    if (StringUtils.isEmpty(productId)) {
                        throw new RuntimeException("收卡啦没有对应的产品" + quota.toString());
                    }
                    param.put("productId", productId);
                } else {
                    throw new RuntimeException("收卡啦产品获取失败");
                }
            } else {
                param.put("productId", ProductData.productMap.get(operatorCode + nameMd5).get(quota.toString()));
            }
            //拼接参数顺序
            String paramMd5str = "userCodeproductIdcardPwddateTimecardNoretUrluserOrderNo";
            for (String key : param.keySet()) {
                paramMd5str = paramMd5str.replace(key, param.get(key));
            }
            paramMd5str = paramMd5str.concat(signKey);

            String sign = EncryptionUtil.getMD5(paramMd5str).toLowerCase();
            param.put("sign", sign);
            log.info("向收卡啦销卡提交数据：" + JSONObject.toJSONString(param));
            String resultStr = HttpUtil.sendPost(httpUrl, param, "utf-8");
            log.info("收卡啦销卡返回：" + resultStr);
            if (!StringUtils.isEmpty(resultStr)) {
                JSONObject resul = JSONObject.parseObject(resultStr);
                if (resul != null && resul.get("result") != null) {
                    return true;
                } else {
                    JSONObject body = new JSONObject();
                    body.put("apiSign", "pmy2019app");
                    body.put("approveStatus", false);
                    body.put("orderNo", order.getString("orderNo"));
                    body.put("itemQuota", null);
                    body.put("costAmount", null);
                    body.put("adminApprove", false);
                    body.put("remark", ShouKaStatusMsg.valueOf("code_" + resul.getString("code")).getMessage());
                    String result = HttpUtil.sendPostJson(approveUrl, body.toJSONString(), "utf-8");
                    JSONObject resJson = JSONObject.parseObject(result);
                    if (resJson.getBoolean("success") || resJson.getIntValue("code") == 505) {
                        return true;
                    }
                }
            }
        } catch (Exception e) {
            log.error("收卡提交错误");
            e.printStackTrace();
            return false;
        }
        return false;
    }

    private Map<String, String> getProductId (String operatorCode, String operatorName) {
        try {
            Map<String, String> resultMap = new HashMap<>();
            Map<String, String> param = new HashMap<>();
            param.put("userCode", customerId);
            param.put("operatorCode", operatorCode);
            param.put("name", operatorName);
            param.put("dateTime", DateUtil.DateToString(new Date(), DateStyle.YYYYMMDDHHMMSS));
            //拼接参数顺序
            String paramMd5str = "userCodedateTime";
            for (String key : param.keySet()) {
                paramMd5str = paramMd5str.replace(key, param.get(key));
            }
            paramMd5str = paramMd5str.concat(signKey);
            String sign = ShouKaUtil.MD5(paramMd5str);
            param.put("sign", sign);
            String resultStr = HttpUtil.sendPost("http://api.shoukala.com:8088/query/priceQuery", param, "utf-8");
            log.info("获取收卡啦产品id：" + resultStr);
            JSONObject jsonObject = JSONObject.parseObject(resultStr);
            JSONArray jsonArray = jsonObject.getJSONArray("result");
            String nameMd5 = EncryptionUtil.getMD5(operatorName);
            if (jsonArray != null) {
                for (Object pro : jsonArray) {
                    JSONObject object = (JSONObject) pro;
                    if (object.getString("state").equals("1")) {
                        if (object.get("api_code") !=  null) {
                            resultMap.put(object.getString("face_value"), object.getString("api_code"));
                        }
                    }
                }
            }
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 销卡回调处理
     *
     * @param param
     */
    @Override
    public boolean cardNotify(ResultParam param) {
        String userOrderNo = param.getUserOrderNo();
        Float accountValue  = param.getAccountValue();
        String dateTime = param.getDateTime();
        Integer faceValue  = param.getFaceValue();
        String cardStatus  = param.getCardStatus();
        String productName  = param.getProductName();
        String realFaceValue  = param.getRealFaceValue();
        String sign  = param.getSign();
        String[] signPre = new String[]{userOrderNo, dateTime, signKey};
        String signStr = String.join("", signPre);
        //添加收卡啦 订单号 //2019-09-27
        String thirdOrderNo = param.getOrderNo();
        log.info("收卡啦销卡回调：" + signStr);
        try {
            String signMy = EncryptionUtil.getMD5(signStr).toLowerCase();
            log.info("收卡啦销卡签名比对，我方：" + signMy + ",他方：" + sign + ", 比对结果：" + signMy.equals(sign));
            if (signMy.equals(sign)) {
                if (cardStatus.equals("2011")) {//成功
                    JSONObject body = new JSONObject();
                    body.put("apiSign", "pmy2019app");
                    body.put("approveStatus", true);
                    body.put("orderNo", userOrderNo);
                    body.put("itemQuota", new BigDecimal(realFaceValue).intValue());
                    body.put("costAmount", accountValue);
                    body.put("remark", "成功");
                    body.put("adminApprove", false);
                    body.put("thirdOrderNo", thirdOrderNo);
                    String result = HttpUtil.sendPostJson(approveUrl, body.toJSONString(), "utf-8");
                    JSONObject resJson = JSONObject.parseObject(result);
                    if (resJson.getBoolean("success")) {
                        return true;
                    }
                } else if (cardStatus.equals("2012")) {//失败
                    JSONObject body = new JSONObject();
                    body.put("apiSign", "pmy2019app");
                    body.put("approveStatus", false);
                    body.put("orderNo", userOrderNo);
                    body.put("itemQuota", new BigDecimal(realFaceValue).intValue());
                    body.put("costAmount", accountValue);
                    body.put("remark", "失败");
                    body.put("adminApprove", false);
                    body.put("thirdOrderNo", thirdOrderNo);
                    String result = HttpUtil.sendPostJson(approveUrl, body.toJSONString(), "utf-8");
                    JSONObject resJson = JSONObject.parseObject(result);
                    if (resJson.getBoolean("success")) {
                        return true;
                    }
                } else if (cardStatus.equals("2014")) {//失败
                    JSONObject body = new JSONObject();
                    body.put("apiSign", "pmy2019app");
                    body.put("approveStatus", false);
                    body.put("orderNo", userOrderNo);
                    body.put("itemQuota", new BigDecimal(realFaceValue).intValue());
                    body.put("costAmount", accountValue);
                    body.put("remark", "高于实际面值,扣除金额");
                    body.put("adminApprove", false);
                    body.put("thirdOrderNo", thirdOrderNo);
                    String result = HttpUtil.sendPostJson(approveUrl, body.toJSONString(), "utf-8");
                    JSONObject resJson = JSONObject.parseObject(result);
                    if (resJson.getBoolean("success")) {
                        return true;
                    }
                } else if (cardStatus.equals("2013")) {//成功
                    JSONObject body = new JSONObject();
                    body.put("apiSign", "pmy2019app");
                    body.put("approveStatus", true);
                    body.put("orderNo", userOrderNo);
                    body.put("itemQuota", realFaceValue);
                    body.put("costAmount", accountValue);
                    body.put("remark", "低于实际面值，按提交面值结算");
                    body.put("adminApprove", false);
                    body.put("thirdOrderNo", thirdOrderNo);
                    String result = HttpUtil.sendPostJson(approveUrl, body.toJSONString(), "utf-8");
                    JSONObject resJson = JSONObject.parseObject(result);
                    if (resJson.getBoolean("success")) {
                        return true;
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return false;
    }

    /**
     * @return
     */
    @Override
    public Object returnOk() {
        return "success";
    }

    public static void main(String[] args) {
        try {
            Map<String, String> param = new HashMap<>();
            param.put("userCode", customerId);
            param.put("operatorCode", "1");
            param.put("retUrl", "www.baidu.com");
            param.put("productId", "50001");
            param.put("dateTime", DateUtil.DateToString(new Date(), DateStyle.YYYYMMDDHHMMSS));
            String retUrl = param.get("retUrl");
            param.put("userOrderNo", "11223344556677");
            param.put("cardNo", "2323232323323");
            param.put("cardPwd", ShouKaUtil.encrypt("2323232323232323", paramKey));
            //拼接参数顺序
            String paramMd5str = "userCodeproductIdcardPwddateTimecardNoretUrluserOrderNo";
            for (String key : param.keySet()) {
                paramMd5str = paramMd5str.replace(key, param.get(key));
            }
            paramMd5str = paramMd5str.concat(signKey);
            System.out.println(paramMd5str);
            String sign = ShouKaUtil.MD5(paramMd5str);
            param.put("sign", sign);
            String resultStr = HttpUtil.sendPost("http://api.shoukala.com:8088/apply/card", param, "utf-8");
            System.out.println(resultStr);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
